﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Printing;
using ComLib.ComFun;
using SuperSocket.ClientEngine;
using System.Net;
using IPrinting;
using Spire.Pdf;

namespace TestPhotoPrinting
{
    public partial class FormSelectPriniting : Form
    {
        private string strDefaultFolder = "D:\\Photos";

        private string strIniFilePath = Path.Combine(Application.StartupPath, "PhotoPrinter.ini");

        private string SelectedFile = "";

        private string OutputPDFFile = "";

        private bool _bInitFinished = false;

        private ConfigDirectory _dirConfig = null;

        /// <summary>
        /// 指示当前是否具备打印目标允许打印
        /// </summary>
        private bool _canPrinting = false;

        private List<string> _printers = new List<string>();

        private static PrintDocument fPrintDocument = new PrintDocument();

        //获取本机默认打印机名称  
        public static String DefaultPrinter()
        {
            return fPrintDocument.PrinterSettings.PrinterName;
        }

        public FormSelectPriniting()
        {
            _dirConfig = new ConfigDirectory();
            InitializeComponent();
        }

        private void InitComboxBoxs()
        {
            comboBoxPrintingInterface.Items.Clear();
            foreach (InterfaceConfig config in ListInterfaces)
            {
                comboBoxPrintingInterface.Items.Add(config.InterfaceName);
            }
            comboBoxPrintingInterface.SelectedIndex = 1;
        }

        private bool SelectPrinter(string printer)
        {
            int i = _printers.IndexOf(printer);
            if (i != -1)
            {
                comboBoxPrinterList.SelectedIndex = i;
                return true;
            }
            return false;
        }

        private string GetSavePrinter()
        {
            return IniFile.IniValue("base", "Printer", strIniFilePath);
        }

        private void SavePrinter(string strValue)
        {
            IniFile.WriteValue("base", "Printer", strValue, strIniFilePath);
        }

        private void InitCtrls()
        {
            strDefaultFolder = IniFile.IniValue("base", "DefaultBrowseFolder", strIniFilePath);
            _bInitFinished = false;
            comboBoxPrinterList.Items.Clear();
            _printers = PrinterService.Printers;
            foreach (string name in _printers)
            {
                comboBoxPrinterList.Items.Add(name);
            }
            string printerName = GetSavePrinter();
            SelectPrinter(printerName);
            _bInitFinished = true;
            btnDoPrint.Enabled = _canPrinting;
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            SelectedFile = "";
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "JPEG图像|*.jpg|BMP图像|*.bmp|PNG图像|*.png";
            dlg.InitialDirectory = strDefaultFolder;
            if (DialogResult.OK == dlg.ShowDialog())
            {
                SelectedFile = dlg.FileName;
                picShow.Image = Image.FromFile(SelectedFile);
                _canPrinting = true;
                btnDoPrint.Enabled = _canPrinting;
            }
        }

        private void buttonSetDefPath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                strDefaultFolder = dlg.SelectedPath;
                IniFile.WriteValue("base", "DefaultBrowseFolder", strDefaultFolder, strIniFilePath);
            }
        }

        private void btnDoPrint_Click(object sender, EventArgs e)
        {
            if (!File.Exists(SelectedFile))
            {
                MessageBox.Show("请选择打印照片!");
                return;
            }
            btnDoPrint.Enabled = false;
            PrintDataPackge pack = new PrintDataPackge();
            pack.Invoker = comboBoxPrintingInterface.SelectedItem.ToString();
            if (radioButtonPrint.Checked)
            {
                pack.Action = IPrinting.PrintAction.Print;
                pack.Add("PhotoPath", SelectedFile);
                pack.Add("PhotoName", Path.GetFileNameWithoutExtension(SelectedFile));
            }
            else if (radioButtonCropPrint.Checked)
            {
                pack.Action = IPrinting.PrintAction.CropPrint;
                pack.Add("OriginalPhotoPath", SelectedFile);
                pack.Add("PhotoName", Path.GetFileNameWithoutExtension(SelectedFile));
            }          
            SendDataToServer(pack);
        }

        private void comboBoxPrinterList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!_bInitFinished)
            {
                return;
            }
            string printer = comboBoxPrinterList.SelectedItem.ToString();
            SavePrinter(printer);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            LoadInterface();
            InitCtrls();
            InitComboxBoxs();
        }

        private bool Connected = false;

        private List<InterfaceConfig> ListInterfaces = new List<InterfaceConfig>();
      
        private void LoadInterface()
        {
            //配置文件路径
            string file = Application.StartupPath + "\\Config\\" + "Interfaces.xml";
            InterfaceConfigReader<InterfaceConfig> reader = new InterfaceConfigReader<InterfaceConfig>(file);
            //读配置
            if (!reader.Load())
            {
                MessageBox.Show("设备配置信息加载失败!\n" + reader.ErrorMessage);
            }
            ListInterfaces = reader.ListInterfaces;
        }

        public EasyClient<PrintResponsePackageInfo> ssClient = null;

        public void ConnectToServer()
        {
            ssClient = new EasyClient<PrintResponsePackageInfo>();
            ssClient.Initialize(new PrintResponseReceiveFilter());
            ssClient.Connected += OnClientConnected;
            ssClient.NewPackageReceived += OnPackageReceived;
            ssClient.Error += OnClientError;
            ssClient.Closed += OnClientClosed;
            ssClient.ConnectAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7779));
        }

        private void OnPackageReceived(object sender, PackageEventArgs<PrintResponsePackageInfo> e)
        {
            if (this.InvokeRequired)
            {
                EventHandler<PackageEventArgs<PrintResponsePackageInfo>> handler = new EventHandler<PackageEventArgs<PrintResponsePackageInfo>>(OnPackageReceived);
                this.BeginInvoke(handler, new object[] { sender, e });
                return;
            }
            PrintResponsePackageInfo packageInfo = e.Package;
            PrintResponsePackge pack = packageInfo.Packge;
            richTextBoxReceived.AppendText(pack.OutParams + Environment.NewLine);
            switch (packageInfo.Result)
            {
                case PrintResult.InitOK:
                    break;
                case PrintResult.InitFailed:
                    break;
                case PrintResult.ExitOK:
                    break;
                case PrintResult.ExitFailed:
                    break;
                case PrintResult.PrintOK:
                    OutputPDFFile = pack["OutputPDFFile"];
                    //buttonPreview.Enabled = true;
                    MessageBox.Show("打印成功!");
                    break;
                case PrintResult.PrintFailed:
                    MessageBox.Show("打印失败:" + pack.Message);
                    btnDoPrint.Enabled = true;
                    break;
                case PrintResult.CropPrintOK:
                    OutputPDFFile = pack["OutputPDFFile"];
                    MessageBox.Show("裁切打印成功!");
                    break;
                case PrintResult.CropPrintFailed:
                    MessageBox.Show("裁切打印失败:" + pack.Message);
                    btnDoPrint.Enabled = true;
                    break;
                case PrintResult.ClearOK:
                    break;
                case PrintResult.ClearFailed:
                    break;
                case PrintResult.Timeout:
                    break;
                case PrintResult.CatchException:
                    break;
                default:
                    break;
            }
        }

        private void OnClientConnected(object sender, EventArgs e)
        {
            if (this.InvokeRequired)
            {
                EventHandler handler = new EventHandler(OnClientConnected);
                this.BeginInvoke(handler, new object[] { sender, e });
                return;
            }
            Connected = true;
            richTextBoxReceived.AppendText("已连接到服务器..." + Environment.NewLine);
        }

        private void OnClientClosed(object sender, EventArgs e)
        {
            if (this.InvokeRequired)
            {
                EventHandler handler = new EventHandler(OnClientConnected);
                this.BeginInvoke(handler, new object[] { sender, e });
                return;
            }
            richTextBoxReceived.AppendText("连接已断开..." + Environment.NewLine);
        }

        private void OnClientError<ErrorEventArgs>(object sender, ErrorEventArgs e)
        {
            if (this.InvokeRequired)
            {
                EventHandler handler = new EventHandler(OnClientError);
                this.BeginInvoke(handler, new object[] { sender, e });
                return;
            }
            richTextBoxReceived.AppendText("客户端错误：" + e.ToString() + Environment.NewLine);
        }

        private void buttonConnect_Click(object sender, EventArgs e)
        {
            ConnectToServer();
        }

        private void buttonDisconnect_Click(object sender, EventArgs e)
        {
            if (Connected)
            {
                ssClient.Close();
                Connected = false;
            }
        }

        private void buttonLogin_Click(object sender, EventArgs e)
        {
            PrintDataPackge pack = new PrintDataPackge();
            pack.Invoker = comboBoxPrinterList.SelectedItem.ToString();
            pack.Action = IPrinting.PrintAction.Init;
            pack.Add("Path", @"D:\Newest");
            pack.Add("Key", "Login");
            SendDataToServer(pack);
        }

        private void SendDataToServer(PrintDataPackge sendPackge)
        {
            byte[] dataBody = MsgPackHandler.ConvertToBytes<PrintDataPackge>(sendPackge);

            // 协议命令占16位, 如果占的位数长过协议，那么协议解析会出错的
            var commandData = Encoding.UTF8.GetBytes(sendPackge.Action);

            // 长度int类型占4位，根据协议这里也只能4位，否则会出错
            var dataLen = BitConverter.GetBytes(dataBody.Length);

            // 命令加内容长度为20
            var sendData = new byte[20 + dataBody.Length];
            // +-------+---+-------------------------------+
            // |request |  l |                               |
            // | name   | e |    request body       |
            // |  (16 )    | n |                               |
            // |             |(4)|                               |
            // +-------+---+-------------------------------+
            Array.ConstrainedCopy(commandData, 0, sendData, 0, commandData.Length);
            Array.ConstrainedCopy(dataLen, 0, sendData, 16, 4);
            Array.ConstrainedCopy(dataBody, 0, sendData, 20, dataBody.Length);
            ssClient.Send(sendData);
        }

        private void ShowPreviewImage()
        {
            string previewFile = string.Format("{0}\\{1}.png", _dirConfig.Preview, Path.GetFileNameWithoutExtension(SelectedFile));
            if (File.Exists(previewFile))
            {
                System.Diagnostics.Process.Start(previewFile);
                return;
                //return Image.FromFile(previewFile);
            }
            Image image = null;
            //Open pdf document
            PdfDocument doc = new PdfDocument();
            doc.LoadFromFile(OutputPDFFile);

            //Save to images
            image = doc.SaveAsImage(0, 300, 300);
            image.RotateFlip(RotateFlipType.Rotate90FlipNone);
            image.Save(previewFile, System.Drawing.Imaging.ImageFormat.Png);
            doc.Close();
            System.Diagnostics.Process.Start(previewFile);
        }

        private void buttonPreview_Click(object sender, EventArgs e)
        {
            if (!File.Exists(OutputPDFFile))
            {
                MessageBox.Show("找不到已经打印过的文件.");
                return;
            }
            ShowPreviewImage();
        }

    }
}
